/*
 * Copyright 2010 Gal Dolber.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.unnison.demo.client.jsonserializer;

import com.google.gwt.resources.client.CssResource;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.inject.Inject;

import com.unnison.demo.client.jsonserializer.JsonSerializerPresenter.JsonSerializerBinder;
import com.unnison.demo.client.main.MainPresenter;
import com.unnison.framework.client.GuitPresenter;
import com.unnison.framework.client.binder.GuitBinder;
import com.unnison.framework.client.binder.ViewField;
import com.unnison.framework.client.binder.ViewHandler;
import com.unnison.framework.client.binder.contributor.Debug;
import com.unnison.framework.client.binder.contributor.RunAsync;
import com.unnison.framework.client.binder.contributor.UserAction;
import com.unnison.framework.client.binder.useraction.Category;
import com.unnison.framework.client.binder.useraction.HasUserActionValue;
import com.unnison.framework.client.jsorm.JsonSerializer;
import com.unnison.framework.client.place.PlaceDataEncrypted;
import com.unnison.framework.client.place.Place;
import com.unnison.framework.client.place.PlaceName;

import java.util.Date;

@RunAsync
@Category("Json serializer")
@PlaceName("json")
@PlaceDataEncrypted
public class JsonSerializerPresenter extends GuitPresenter<JsonSerializerBinder> implements Place<Person>, HasUserActionValue {

    public static interface CustomStyle extends CssResource {
        String style1();

        String style2();
    }

    public interface JsonSerializerBinder extends GuitBinder<JsonSerializerPresenter> {
    }

    public static interface PersonSerializer extends JsonSerializer<Person> {
    }

    // Count actions for user action tracking
    private int actionsCount = 0;

    @ViewField
    CustomStyle style;

    @ViewField("name")
    HasStyleName nameStyle;

    @ViewField
    HasText name;

    @ViewField
    HasText id;

    @ViewField
    HasText address;

    @ViewField
    HasText json;

    @ViewField
    HasValue<Date> birthday;
    
    private final PersonSerializer personSerializer;
    private final MainPresenter hasContent;

    Person data;

    @Inject
    public JsonSerializerPresenter(MainPresenter hasContent, PersonSerializer personSerializer) {
        this.hasContent = hasContent;
        this.personSerializer = personSerializer;
    }

    @Override
    public int getUserActionNumber() {
        return actionsCount;
    }

    @Override
    public String getUserActionText() {
        return name.getText();
    }

    @Override
    public void go(Person data) {
        hasContent.setContent(getView(), 5);
        if (data == null) {
            data = new Person();
            data.setAddress("Agate rd 418");
            data.setBirthday(new Date());
            data.setId(13l);
            data.setName("Gal Dolber");
        }
        setPerson(data);
        json.setText(personSerializer.serialize(data));
        this.data = data;
    }

    @ViewHandler
    @Debug
    @UserAction("EditForm")
    void id$name$address$birthday$valueChange() {
        data.setId(Long.parseLong(id.getText()));
        data.setName(name.getText());
        data.setBirthday(birthday.getValue());
        data.setAddress(address.getText());
        placeManager.newItem(JsonSerializerPresenter.class, data);
        json.setText(personSerializer.serialize(data));

        // The user action tracker gets triggered after the handler, so it will never track 0
        actionsCount++;
    }

    @ViewHandler
    @Debug
    @UserAction("Json edited")
    void json$valueChange() {
        data = personSerializer.deserialize(json.getText());
        placeManager.newItem(JsonSerializerPresenter.class, data);
        setPerson(data);

        // The user action tracker gets triggered after the handler, so it will never track 0
        actionsCount++;
    }

    @ViewHandler
    void name$blur() {
        nameStyle.removeStyleName(style.style1());
    }

    @ViewHandler
    void name$focus() {
        nameStyle.setStyleName(style.style1());
    }

    private void setPerson(Person person) {
        id.setText(String.valueOf(person.getId()));
        name.setText(person.getName());
        birthday.setValue(person.getBirthday());
        address.setText(person.getAddress());
    }
}
